import { KubernetesObject, V1ContainerPort, V1HTTPIngressPath, V1Ingress, V1IngressServiceBackend } from "@kubernetes/client-node"
import { K8SResourceType, KV, KVString, PlanContextData } from "yam-types"
import { AccessApproachConfig } from "../types"

export const composeIngress = (
  planData: PlanContextData, appAccess: AccessApproachConfig,
  containerPort: V1ContainerPort, servicePort: number, settings: KV
): KubernetesObject => {
  const isHttp = appAccess.protocol.startsWith("http")
  if (!isHttp || !appAccess.host) {
    throw new Error(`Can not create ingress for ${appAccess.protocol.toUpperCase()} service, please check type or host`)
  }

  const defaultPathType = appAccess.advancedFeatures?.ingressPathType || 'ImplementationSpecific'
  const defaultBackend: V1IngressServiceBackend = {
    port: {
      number: containerPort.containerPort || servicePort
    },
    name: planData.workloadName
  }
  // compose ingress
  const ingress: V1Ingress = {
    apiVersion: "networking.k8s.io/v1",
    kind: K8SResourceType.Ingress,
    metadata: {
      name: planData.workloadName,
      annotations: Object.assign({}, settings.ingressAnnotations, appAccess.advancedFeatures?.ingressAnnotations) as KVString,
      labels: {
        workload: planData.workloadName
      }
    },
    spec: {
      ingressClassName: appAccess.advancedFeatures?.ingressClass,
      tls: [{
        hosts: [appAccess.host],
        secretName: appAccess.cert || settings.defaultTlsCert as string
      }],
      rules: [{
        host: appAccess.host,
        http: {
          paths: (appAccess.paths || ['/']).map(p => {
            if (typeof p === "string") {
              return {
                path: p,
                pathType: defaultPathType,
                backend: {
                  service: defaultBackend
                }
              } as V1HTTPIngressPath
            } else {
              return {
                path: p.path,
                pathType: p.pathType || defaultPathType,
                backend: {
                  service: p.backend || defaultBackend
                }
              } as V1HTTPIngressPath
            }
          })
        }
      }]
    }
  }
  return ingress
}